<?php
// +----------------------------
// | Created by PhpStorm
// +----------------------------
// | Author: YnnSon
// +----------------------------
namespace app\api\service;

use app\api\model\MemberLog;
use app\api\model\MessageDetail;
use app\api\model\Order as OrderModel;
use app\api\model\UserWeixin as UserWeixinModel;
use app\lib\enum\MemberLogEnum;
use app\lib\enum\MessageDetailEnum;
use app\lib\enum\MessageTypeEnum;
use app\lib\enum\OrderStatusEnum;
use app\lib\enum\PaymentEnum;
use app\lib\enum\PayStatusEnum;
use app\lib\enum\ValidEnum;
use think\Config;
use think\Db;
use think\Exception;
use think\Log;
use WeChat\Pay as PaySDK;
use Yurun\Util\HttpRequest;

/**
 * 微信支付通知回调
 * Class WxNotify
 * @package app\api\service
 */
class WxNotify
{
    /**
     * @Desc 微信支付通知处理
     * @return string
     */
    public function notify()
    {
        $pay = new PaySDK(Config::get('wechat'));
        // 获取微信返回的通知信息
        $result = $pay->getNotify();
        // 订单数据处理
        if ($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS') {
            Db::startTrans();
            try {
                $time = time();
                $order_sn = $result['out_trade_no'];
                $order = (new OrderModel)->where('order_sn', '=', $order_sn)->lock(true)->find();
                $orderData = [
                    'transaction_id' => $result['transaction_id'],
                    'pay_time'       => $time,
                    'order_status'   => OrderStatusEnum::PAID,
                    'pay_status'     => PayStatusEnum::PAID,
                ];
                if (OrderStatusEnum::CANCELLED == $order['order_status']) {
                    $orderData['is_invalid'] = ValidEnum::INVALID;
                } else {
                    $orderData['is_invalid'] = ValidEnum::VALID;
                }
                $this->updateOrder($orderData, $order_sn);
                // 生成积分数据
                $memberData = [
                    'user_weixin_id' => $order['user_weixin_id'],
                    'number'         => $order['total_amount'],
                    'type'           => MemberLogEnum::INCREASE,
                    'get_from'       => MemberLogEnum::FROM_CONSUMPTION,
                ];
                // 添加积分记录
                MemberLog::insertMemberData($memberData);
                // 增加积分
                (new UserWeixinModel())->where('id', '=', $order['user_weixin_id'])->setInc('member', $order['total_amount']);
                // 添加一条订单消息
                // $messageData = [
                //     'title'          => MessageDetailEnum::PLACEORDER_TITLE,
                //     'info'           => MessageDetailEnum::PLACEORDER_INFO . date('Y-m-d H:i', $order['subscribe_date']),
                //     'user_weixin_id' => $order['user_weixin_id'],
                //     'message_id'     => MessageTypeEnum::ORDER,
                //     'status'         => MessageDetailEnum::NLOOK,
                // ];
                // MessageDetail::create($messageData);
                Db::commit();
                // +------------------------------------------------------
                // | 收银系统接口
                // +------------------------------------------------------
                $paymentOrderData = [
                    'order_id'  => $order_sn, // 预约平台订单号
                    'type'      => PaymentEnum::SEND_PAY, // 类型,1=支付，2=退款
                    'paytime'   => $time, // 支付时间
                    'new_param' => 1, //
                ];
                $this->sendOrderDataToPayment($paymentOrderData);
            } catch (Exception $e) {
                // 出错啦，处理下吧
                Db::rollback();
                Log::error($e);
                return $e->getMessage() . PHP_EOL;
            }
        }
        // 返回接收成功的回复
        return $pay->getNotifySuccessReply();
    }

    /**
     * @Desc 更新订单状态
     *
     * @param array  $orderData 要更新的数据
     * @param string $order_sn  订单号
     */
    private function updateOrder(array $orderData, $order_sn)
    {
        OrderModel::update($orderData, ['order_sn' => $order_sn]);
    }

    /**
     * @Desc 向收银系统发送订单数据
     *
     * @param array $data 要发送的数据
     *
     * @return mixed
     */
    private function sendOrderDataToPayment($data)
    {
        $url = Config::get('setting.edit_order_url'); // 生产环境接口
        // $url = Config::get('setting.test_edit_order_url'); // 开发环境接口
        return (new HttpRequest())->post($url, $data)->json(true);
    }
}